package web.demo.dao.impl;

import java.sql.Connection;
import java.sql.ParameterMetaData;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.dbutils.handlers.BeanListHandler;

import web.demo.dao.IBaseDao;
import web.demo.utils.JdbcUtils;
import web.demo.utils.LoggableStatement;

import java.io.PrintStream;
public class BaseDao implements IBaseDao{

	protected Connection conn=null;
	private PreparedStatement pstmt=null;
	private ResultSet rs=null;
	
	@Override
	public int update(String sql, Object[] params) {
		conn=JdbcUtils.getConnection();
		try{
			LoggableStatement log=new LoggableStatement(conn,sql);
			pstmt=conn.prepareStatement(sql);
			ParameterMetaData metaData=pstmt.getParameterMetaData();
			//获取占位符个数
			int paramCount=metaData.getParameterCount();
			if(params!=null && paramCount>0){
				for(int i=1;i<=paramCount;i++){
					//给占位符赋值
					pstmt.setObject(i, params[i-1]);
					log.setObject(i,params[i-1]);
				}
			}
			System.out.println(log.getQueryString());
			int result=pstmt.executeUpdate();
			return result;
		}catch(Exception e){
			throw new RuntimeException(e);
		}
	}

	@Override
	public <T> List<T> select(String sql, List<Object> params, Class<T> clazz) {
		conn=JdbcUtils.getConnection();
		try {
			pstmt=conn.prepareStatement(sql);
			ParameterMetaData pMetaData=pstmt.getParameterMetaData();
			int parameterCount=pMetaData.getParameterCount();
			LoggableStatement log=new LoggableStatement(conn,sql);
			if(params!=null && parameterCount>0){
				for(int i=1;i<=parameterCount;i++){
					pstmt.setObject(i,params.get(i-1));
					log.setObject(i, params.get(i-1));
				}
			}
			System.out.println(log.getQueryString());
			rs=pstmt.executeQuery();
			//获取结果集元数据对象
			ResultSetMetaData rsMetaData=pstmt.getMetaData();
			//获取列的个数
			int columnCount=rsMetaData.getColumnCount();
			List<T> list=new ArrayList<T>();
			while(rs.next()){
				T t=clazz.newInstance();
				for(int i=1;i<=columnCount;i++){
					String columnName=rsMetaData.getColumnLabel(i);
					Object columnValue=rs.getObject(columnName);
					BeanUtils.copyProperty(t,columnName,columnValue);
				}
				list.add(t);
			}
			return list;
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}

	public <T> List<T> query(String sql, Object[] params, Class<T> clazz){
		try {
			return JdbcUtils.getQueryRunner().query(sql,new BeanListHandler<T>(clazz),params);
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			throw new RuntimeException(e);
		}
	}
	
	@Override
	public <T> List<T> select(String sql, Class<T> clazz) {
		conn=JdbcUtils.getConnection();
		try {
			pstmt=conn.prepareStatement(sql);
			rs=pstmt.executeQuery();
			ResultSetMetaData rsMetaData=pstmt.getMetaData();
			int columnCount=rsMetaData.getColumnCount();
			List<T> list=new ArrayList<T>();
			while(rs.next()){
				T t=clazz.newInstance();
				for(int i=1;i<=columnCount;i++){
					String columnName=rsMetaData.getColumnLabel(i);
					Object columnValue=rs.getObject(columnName);
					BeanUtils.copyProperty(t,columnName,columnValue);
				}
				list.add(t);
			}
			return list;
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}

	@Override
	public int update(Connection conn, String sql, Object... params) {
		try {
			pstmt = conn.prepareStatement(sql);
			ParameterMetaData pmd=pstmt.getParameterMetaData();
			int paramsCount=pmd.getParameterCount();
			if(paramsCount>0 && params!=null){
				for(int i=1; i<=paramsCount;i++){
					pstmt.setObject(i, params[i-1]);
				}
			}
			return pstmt.executeUpdate();
			
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return -1;
	}
	
}
